package com.dny.asmtop.op;

import com.dny.asmtop.Command;
import com.dny.asmtop.MethodContext;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.commons.GeneratorAdapter;

import java.util.Objects;

/**
 * Created by jlutt on 2018-01-16.
 *
 * @author jlutt
 */
public class CommandIf implements Command {

  private final PredicateDef condition;
  private final Command left;
  private final Command right;

  public CommandIf(PredicateDef condition, Command left, Command right) {
    this.condition = condition;
    this.left = left;
    this.right = right;
  }

  @Override
  public Type type(MethodContext context) {
    return left.type(context);
  }

  @Override
  public Type generator(MethodContext context) {
    Label labelTrue = new Label();
    Label labelExit = new Label();

    GeneratorAdapter g = context.getGeneratorAdapter();
    condition.generator(context);
    g.push(true);

    g.ifCmp(condition.type(context), GeneratorAdapter.EQ, labelTrue);

    if (right != null) {
      right.generator(context);
    }

    g.goTo(labelExit);

    g.mark(labelTrue);
    left.generator(context);

    g.mark(labelExit);
    return left.type(context);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    CommandIf commandIf = (CommandIf) o;
    return Objects.equals(condition, commandIf.condition) &&
        Objects.equals(left, commandIf.left) &&
        Objects.equals(right, commandIf.right);
  }

  @Override
  public int hashCode() {
    return Objects.hash(condition, left, right);
  }
}
